#!/usr/bin/perl -w 
# 20 CUDA benchmarks, Inti
# 13 rodinia benchmarks, Titan
# 6  parboil benchmarks, Inti
# 39 benchmarks in total

use English;

@myorder = ("SAD", "PVC", "SSC", "BFS", "MUM", "CFD", "KMN", "SCP", "FWT", "IIX", "SPMV", "JPEG", "BFSR", "SC", "FFT", "SD2", "WP", "PVR", "BP", "LIB", "CON", "AES","SD1","BLK", "HS", "SLA","DN", "LPS", "NN", "PFN", "LYTE", "LUD", "MM", "STO", "CP", "NQU", "CUTP", "HW", "TPAF");

@mylist = ("parboil/sad/output_sad.txt", "Mars/PageViewCount/output_PVC.txt", "Mars/SimilarityScore/output_SSC.txt", "CUDA/BFS/output_BFS.txt", "CUDA/MUM/output_MUM.txt", "rodinia/cfd/output_cfd.txt", "CUDA/kmeans/output_kmeans.txt", "CUDA/SCP/output_SCP.txt",  "CUDA/FWT/output_FWT.txt","Mars/InvertedIndex/output_IIX.txt","parboil/spmv/output_spmv.txt", "CUDA/JPEG/output_JPEG.txt",  "rodinia/bfs/output_bfs.txt", "rodinia/streamcluster/output_streamcluster.txt", "parboil/fft/output_fft.txt", "rodinia/srad_v2/output_srad_v2.txt", "CUDA/WP/output_WP.txt",
"Mars/PageViewRank/output_PVR.txt",
"rodinia/backprop/output_backprop.txt", "CUDA/LIB/output_LIB.txt", "CUDA/CON/output_CON.txt","CUDA/AES/output_AES.txt","rodinia/srad_v1/output_srad_v1.txt","CUDA/BlackScholes/output_BlackScholes.txt", "rodinia/hotspot/output_hotspot.txt", "CUDA/SLA/output_SLA.txt",  "CUDA/denoise/output_denoise.txt","CUDA/LPS/output_LPS.txt", "CUDA/NN/output_NN.txt","rodinia/pf_naive/output_pf_naive.txt", "rodinia/leukocyte/output_leukocyte.txt", "rodinia/lud/output_lud.txt","parboil/mm/output_mm.txt", "CUDA/STO/output_STO.txt", "CUDA/CP/output_CP.txt", "CUDA/NQU/output_NQU.txt", "parboil/cutcp/output_cutcp.txt", "rodinia/heartwall/output_heartwall.txt","parboil/tpacf/output_tpacf.txt");

@file_list = (@mylist);
@benchmarks = (@myorder);
$result_file = "all_results.txt";

open(OUTPUT, ">$result_file") || die "Cannot open file $result_file for writing\n";

for ($j = 0; $j <= $#file_list; $j++) {  

	my $ipc = `grep gpu_tot_ipc $file_list[$j] | tail -n 1 | awk '\{print \$3\}'`;
	chomp($ipc);
	push @globalipc, $ipc;
		
	my $ins = `grep gpu_tot_sim_insn $file_list[$j] | tail -n 1 | awk '\{print \$3\}'`;
	chomp($ins);
	push @globalins, $ins;	
	
	my $total_demand_rgl = `grep \"GPU_DEMAND_READ_LOCAL_GLOBAL \" $file_list[$j] | tail -n 1 | awk '\{print \$3\}'`;
    chomp($total_demand_rgl);
    push @globaldemand_rgl, $total_demand_rgl;
	
    my $total_demand = `grep \"gpgpu_total_demand_init \" $file_list[$j] | tail -n 1 | awk '\{print \$3\}'`;
	chomp($total_demand);
	push @globaltotal_demand, $total_demand;	
	
	my $L1readhit = `grep  "L1 read hit" $file_list[$j] | tail -n  1 | awk '\{print \$5\}'`;
	chomp($L1readhit);
	push @globalL1readhit, $L1readhit;
	
	my $L1readmiss = `grep  "L1 read misses" $file_list[$j] | tail -n  1 | awk '\{print \$5\}'`;
	chomp($L1readmiss);
	push @globalL1readmiss, $L1readmiss;

    #push @globalL1missrate, ($L1readmiss)/($L1readhit + $L1readmiss);
	
    my $L2readhit = `grep  "L2_read_hit" $file_list[$j] | tail -n  1 | awk '\{print \$3\}'`;
	chomp($L2readhit);
	push @globalL2readhit, $L2readhit;
	
	my $L2readmiss = `grep  "L2_read_miss" $file_list[$j] | tail -n  1 | awk '\{print \$3\}'`;
	chomp($L2readmiss);
	push @globalL2readmiss, $L2readmiss;
	
   	my $L2writehit = `grep  "L2_write_hit" $file_list[$j] | tail -n  1 | awk '\{print \$3\}'`;
	chomp($L2writehit);
	push @globalL2writehit, $L2writehit;
        
	# my $L2writemiss = `grep  "L2_write_miss" $file_list[$j] | tail -n  1 | awk '\{print \$3\}'`;
	# chomp($L2writemiss);
	# push @globalL2writemiss, $L2writemiss;
	
	#push @globalL2missrate, ($L2readmiss)/($L2readhit + $L2readmiss);
    #push @globalL2writemissrate, ($L2writemiss)/($L2writehit + $L2writemiss);

	my $Stall = `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$2\}' |  awk '\{print \$1\}'`;
	chomp($Stall);
	push @globalStall, $Stall;
	
	my $W0Idle= `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$3\}' |  awk '\{print \$1\}'`;
	chomp($W0Idle);
	push @globalW0Idle, $W0Idle;
	
	my $W0Mem = `grep "Stall" $file_list[$j] | tail -n 1 |  awk -F ':' '\{print \$4\}' |  awk '\{print \$1\}'`;
	chomp($W0Mem);
	push @globalW0Mem, $W0Mem;

    my $latency1 = `grep "average latency" $file_list[$j] | tail -n 2| head -n 1| awk '\{print \$5\}'`;
    chomp($latency1);
    push @globallatency1, $latency1;

	my $latency2 = `grep "average latency" $file_list[$j] | tail -n 1| awk '\{print \$5\}'`;
    chomp($latency2);
    push @globallatency2, $latency2;
    
	@dram_eff = `grep "dram_eff=" $file_list[$j] | tail -n 8 |  awk '\{print \$2\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@dram_eff);
	push @globaldram_eff, [avg(\@dram_eff)];
	
	@precharge = `grep "n_pre=" $file_list[$j] | tail -n 8 |  awk '\{print \$4\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@precharge);
	push @globalprecharge, [avg(\@precharge)];
	
	@activate = `grep "n_act=" $file_list[$j] | tail -n 8 |  awk '\{print \$3\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@activate);
	push @globalactivate, [avg(\@activate)];
	
	@dram_util = `grep "bw_util" $file_list[$j] | tail -n 8 |  awk '\{print \$8\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@dram_util);
	push @globaldram_util, [avg(\@dram_util)];

   	my $total_dram_queue = `grep "DRAM_QUEUE_TIME" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($total_dram_queue);
    push @globaltotal_dram_queue, $total_dram_queue;
	
	my $total_dram_spent = `grep "DRAM_SPENT_TIME" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
 	chomp($total_dram_spent);
    push @globaltotal_dram_spent, $total_dram_spent;
	
	my $row_locality = `grep "row_locality" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($row_locality);
    push @globalrow_locality, $row_locality;

	my $averagemflatency = `grep "averagemflatency" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($averagemflatency);
    push @globalaveragemflatency, $averagemflatency;
	
   	my $dram_stall = `grep "gpu_stall_dramfull" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
	chomp($dram_stall);
    push @globaldram_stall, $dram_stall;
	
    my $mshr_stall = `grep "gpu_stall_by_MSHRwb" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
   	chomp($mshr_stall);
    push @globalmshr_stall, $mshr_stall;
	
	@AVG_BLP = `grep "AVG_BLP" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@AVG_BLP);
	push @globalAVG_BLP, [avg(\@AVG_BLP)];
	
    my $NEW_BLP = `grep "NEW_BLP" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
   	chomp($NEW_BLP);
    push @globalNEW_BLP, $NEW_BLP;
    
	my $NEW_WAITBLP = `grep "NEW_WAITBLP" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
   	chomp($NEW_WAITBLP);
    push @globalNEW_WAITBLP, $NEW_WAITBLP;

    my $NEW_OCC = `grep "NEW_OCC" $file_list[$j] | tail -n 1 |  awk '\{print \$3\}'`;
   	chomp($NEW_OCC);
    push @globalNEW_OCC, $NEW_OCC;
	
	@stress_avg = `grep "stress: count=" $file_list[$j] | tail -n 8 | awk '\{print \$3\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@stress_avg);
	push @globalstress_avg, [avg(\@stress_avg)];

	@queue_max = `grep "mrqq: max=" $file_list[$j] | tail -n 8 | awk '\{print \$2\}' |  awk -F '=' '\{print \$2\}'`;
	chomp(@queue_max);
	push @globalqueue_max, [avg(\@queue_max)];
	
	@how_many = `grep "how_many" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@how_many);
	push @globalhow_many, [avg(\@how_many)];
	
	@ctas_per_group = `grep "ctas_per_group" $file_list[$j] | awk '\{print \$3\}'`;
	chomp(@ctas_per_group);
	push @globalctas_per_group, [avg(\@ctas_per_group)];
	
} 

 	# General ----------------------------------
	print OUTPUT "Benchmarks \t";
	print OUTPUT "IPC\t";
	print OUTPUT "INS\t";
	print OUTPUT "Dem-RGL\t";  
	print OUTPUT "Total\t";  

	# Network Related --------------------------
    print OUTPUT "latency1  \t";
	print OUTPUT "latency2  \t";
	
	# DRAM Related -----------------------------
	print OUTPUT "AVG_BLP \t";
	print OUTPUT "NEW_BLP \t";
	print OUTPUT "NEW_WAITBLP \t";
	print OUTPUT "NEW_OCC \t";
	print OUTPUT "Stress \t";
	print OUTPUT "Row-Local \t";
	
	print OUTPUT "DRAM-eff \t";
	print OUTPUT "DRAM-util \t";
	print OUTPUT "Precharge \t";
	print OUTPUT "Activate \t";
	
	# Latency Related
	print OUTPUT "DRAM-Queue \t";
	print OUTPUT "DRAM-Spent \t";
	print OUTPUT "Avg-fetch \t";
	print OUTPUT "MSHR_STALL \t";
	print OUTPUT "DRAM_STALL \t";

	# Cache Related ----------------------------
	print OUTPUT "L1 R-H \t";
	print OUTPUT "L1 R-M \t";
	print OUTPUT "L2 R-H \t";
	print OUTPUT "L2 R-M \t";
	print OUTPUT "L2 W-H \t";
	#print OUTPUT "L2 R-MR \t";
	#print OUTPUT "L2 W-MR \t";
	
	# Warp Related -----------------------------
	print OUTPUT "Stall \t";
	print OUTPUT "W0Idle \t";
	print OUTPUT "W0Mem \t";
	
	# MISC (Stats -- One time)
	print OUTPUT "QMax \t";
	print OUTPUT "how_many \t";
	print OUTPUT "ctas_per_group \t";
	
	print OUTPUT "\n";


for ($k = 0;$k <= $#file_list;$k++) 
{
    # BASELINE Starts ----------------------------------------------------------------
 	# General ----------------------------------
	print OUTPUT "$benchmarks[$k] \t";
	print OUTPUT "$globalipc[$k] \t";
	print OUTPUT "$globalins[$k] \t";
	print OUTPUT "$globaldemand_rgl[$k] \t";
	print OUTPUT "$globaltotal_demand[$k] \t";

	# Network Related --------------------------
    print OUTPUT "$globallatency1[$k] \t";
	print OUTPUT "$globallatency2[$k] \t";
	
	# DRAM Related -----------------------------
	print OUTPUT "$globalAVG_BLP[$k][0] \t";
	print OUTPUT "$globalNEW_BLP[$k] \t";
	print OUTPUT "$globalNEW_WAITBLP[$k] \t";
	print OUTPUT "$globalNEW_OCC[$k] \t";
	print OUTPUT "$globalstress_avg[$k][0] \t";
	print OUTPUT "$globalrow_locality[$k] \t";
	
	print OUTPUT "$globaldram_eff[$k][0] \t";
	print OUTPUT "$globaldram_util[$k][0] \t";
	print OUTPUT "$globalprecharge[$k][0] \t";
	print OUTPUT "$globalactivate[$k][0] \t";
	
	# Latency Related -----------------------------
	print OUTPUT "$globaltotal_dram_queue[$k] \t";
	print OUTPUT "$globaltotal_dram_spent[$k] \t";
	print OUTPUT "$globalaveragemflatency[$k] \t";
	print OUTPUT "$globalmshr_stall[$k] \t";
	print OUTPUT "$globaldram_stall[$k] \t";

	# Cache Related ----------------------------
	print OUTPUT "$globalL1readhit[$k] \t";
	print OUTPUT "$globalL1readmiss[$k] \t";
	print OUTPUT "$globalL2readhit[$k] \t";
	print OUTPUT "$globalL2readmiss[$k] \t";
	print OUTPUT "$globalL2writehit[$k] \t";
	#print OUTPUT "$globalL2missrate[$k] \t";
	#print OUTPUT "$globalL2writemissrate[$k] \t";

	# Warp Related -----------------------------
	print OUTPUT "$globalStall[$k] \t";
	print OUTPUT "$globalW0Idle[$k] \t";
	print OUTPUT "$globalW0Mem[$k] \t";
 	# Add for Distribution -- Branch Divergence
	
	#MISC
	print OUTPUT "$globalqueue_max[$k][0] \t";
	
	print OUTPUT "$globalhow_many[$k][0] \t";
	print OUTPUT "$globalctas_per_group[$k][0] \t";
	
	
	# BASELINE Over ----------------------------------------------------------------
	
	print OUTPUT "\n";
}


sub avg {
	@_ == 1 or die ('Sub usage: $avg = avg(\@array);');
	my ($array_ref) = @_;
	my $sum;
	my $count = scalar @$array_ref;
        if ($count == 0) {
                return 0;
        }
	foreach (@$array_ref) { $sum += $_; }
	return $sum / $count;
}

sub max {
	@_ == 1 or die ('Sub usage: $max = max(\@array);');
	my ($array_ref) = @_;
	my $maxval = -999999999999999999;
	foreach (@$array_ref)
	{
		if ( $maxval < $_ )
		{
			$maxval = $_;
		}
	}
	return $maxval;
}

sub sum {
	@_ == 1 or die ('Sub usage: $sum = sum(\@array);');
	my ($array_ref) = @_;
	my $sum;
	foreach (@$array_ref) { $sum += $_; }
	return $sum;
}


#	@queue_avg = `grep "mrqq: max=" $file_list[$j] | tail -n 8 | awk '\{print \$3\}' |  awk -F '=' '\{print \$2\}'`;
#	chomp(@queue_avg);
#	push @globalqueue_avg, [avg(\@queue_avg)];
#	@blp_avg = `grep "blp: count=" $file_list[$j] | tail -n 8 | awk '\{print \$3\}' |  awk -F '=' '\{print \$2\}'`;
#	chomp(@blp_avg);
#	push @globalblp_avg, [avg(\@blp_avg)];
	
